﻿package idv.cjcat.emitter.geom {
	use namespace engine;
	
	import idv.cjcat.emitter.*;
	
	/**
	 * 2D Vector with common vector operations.
	 */
	public class Vector2D {
		
		public var x:Number;
		public var y:Number;
		
		public function Vector2D(x:Number = 0, y:Number = 0) {
			this.x = x;
			this.y = y;
		}
		
		public function clone():Vector2D {
			return new Vector2D(x, y);
		}
		
		/**
		 * Dot product.
		 * @param	vector
		 * @return
		 */
		public function dot(vector:Vector2D):Number {
			return (x * vector.x) + (y * vector.y);
		}
		
		/**
		 * Vector projection.
		 * @param	target
		 * @return
		 */
		public function project(target:Vector2D):Vector2D {
			target = target.unitVec();
			target.length = dot(target);
			return target;
		}
		
		/**
		 * Rotates a clone of the vector.
		 * @param	angle
		 * @param	useRadian
		 * @return The rotated clone vector.
		 */
		public function rotate(angle:Number, useRadian:Boolean = false):Vector2D {
			var temp:Vector2D = new Vector2D(this.x, this.y);
			temp.rotateThis(angle, useRadian);
			return temp;
		}
		
		/**
		 * Rotes the vector.
		 * @param	angle
		 * @param	useRadian
		 */
		public function rotateThis(angle:Number, useRadian:Boolean = false):void {
			if (!useRadian) angle = angle * Math.PI / 180;
			var originalX:Number = x;
			x = originalX * Math.cos(angle) - y * Math.sin(angle);
			y = originalX * Math.sin(angle) + y * Math.cos(angle);
		}
		
		/**
		 * Unit vector.
		 * @return
		 */
		public function unitVec():Vector2D {
			if (length == 0) return new Vector2D();
			return new Vector2D(x / length, y / length);
		}
		
		/**
		 * Vector length.
		 */
		public function get length():Number {
			return Math.sqrt(this.x * this.x + this.y * this.y);
		}
		public function set length(value:Number):void {
			var leng:Number = length;
			
			x = x * value / leng;
			y = y * value / leng;
		}
		
		/**
		 * Sets the vector's both components at once.
		 * @param	x
		 * @param	y
		 */
		public function set(x:Number, y:Number):void {
			this.x = x;
			this.y = y;
		}
		
		/**
		 * The angle between the vector and the positive x axis in degrees.
		 */
		public function get angle():Number { return Math.atan2(y, x) * 180 / Math.PI; }
		public function set angle(value:Number):void {
			var originalLength:Number = length;
			var rad:Number = value * Math.PI / 180;
			x = originalLength * Math.cos(rad);
			y = originalLength * Math.sin(rad);
		}
	}
}